<?php

namespace App\Trip\Orders\BookOrders\Plane\PriceDetails;

use App\Models\Trip\TripOrderCosts\TripOrderCost;
use App\Trip\Orders\BookOrders\Plane\Order\BookNewPlaneOrder;
use App\Trip\Orders\TripNo;
use App\Trip\Passengers\Passengers;
use Exception;
use GuzzleHttp\Exception\GuzzleException;

class BookPlanePriceDetails
{
    private array $passengers;
    private int   $trip_no;
    private array $price_details;
    /**
     * @var float|int
     */
    private float|int $order_amount;
    private float|int $total_construction_fee;
    private float|int $total_fuel_fee;

    /**
     * @throws GuzzleException
     */
    public function __construct(BookNewPlaneOrder $orderInfo)
    {
        $this->passengers = $orderInfo->passengers();
        $this->trip_no    = $orderInfo->getOrderParam()->getTripNo();
        $this->buildPriceDetails();
    }

    /**
     * @throws Exception
     * @throws GuzzleException
     */
    private function buildPriceDetails(): void
    {
        $passengers             = $this->passengers;
        $name                   = TripNo::TRIP_NO_DESC[$this->trip_no];
        $details                = [];
        $total_price            = 0;
        $total_construction_fee = 0;
        $total_fuel_fee         = 0;
        foreach ($passengers as $key => $passenger) {
            $passenger_type                      = $passenger['passenger_type'];
            $passenger_type_name                 = Passengers::PASSENGER_TYPE_DESC[$passenger_type];
            $passengers[$key]['price_details'][] = [
                "type"        => TripOrderCost::COST_TYPE_TICKET,
                "parent_type" => TripOrderCost::COST_TYPE_TICKET,
                "name"        => Passengers::PASSENGER_TYPE_DESC[$passenger_type],
                "price"       => $passenger['ticket_price'],
            ];
            // 票价
            $ticket_price_key = "ticket_price:".$passenger_type_name;
            if (!isset($details[$ticket_price_key])) {
                $details[$ticket_price_key] = [
                    "type"        => TripOrderCost::COST_TYPE_TICKET,
                    "parent_type" => TripOrderCost::COST_TYPE_TICKET,
                    "name"        => $passenger_type_name,
                    "name_uy"     => trans2uy($passenger_type_name),
                    "price"       => $passenger['ticket_price'],
                    "count"       => 1,
                ];
            } else {
                $details[$ticket_price_key]["count"]++;
            }
            $total_price += $passenger['ticket_price'];


            // 机建费
            if ($passenger['construct_fee'] > 0) {
                $construction_fee_key  = "construction_fee:".$passenger_type_name;
                $construction_fee_name = "{$passenger_type_name}机建费";
                if (!isset($details[$construction_fee_key])) {
                    $details[$construction_fee_key] = [
                        "type"        => TripOrderCost::COST_TYPE_PLANE_CONSTRUCTION_FEE,
                        "parent_type" => TripOrderCost::COST_TYPE_PLANE_CONSTRUCTION_FEE,
                        "name"        => $construction_fee_name,
                        "name_uy"     => trans2uy($construction_fee_name),
                        "price"       => $passenger['construct_fee'],
                        "count"       => 1,
                    ];
                } else {
                    $details[$construction_fee_key]["count"]++;
                }
                $passengers[$key]['price_details'][] = [
                    "type"        => TripOrderCost::COST_TYPE_PLANE_CONSTRUCTION_FEE,
                    "parent_type" => TripOrderCost::COST_TYPE_PLANE_CONSTRUCTION_FEE,
                    "name"        => $construction_fee_name,
                    "price"       => $passenger['construct_fee'],
                ];
                $total_price                         += $passenger['construct_fee'];
                $total_construction_fee              += $passenger['construct_fee'];
            }

            // 燃油费
            if ($passenger['fuel_fee'] > 0) {
                $fuel_fee_key  = "fuel_fee:".$passenger_type_name;
                $fuel_fee_name = "{$passenger_type_name}燃油费";
                if (!isset($details[$fuel_fee_key])) {
                    $details[$fuel_fee_key] = [
                        "type"        => TripOrderCost::COST_TYPE_PLANE_FUEL_FEE,
                        "parent_type" => TripOrderCost::COST_TYPE_PLANE_FUEL_FEE,
                        "name"        => $fuel_fee_name,
                        "name_uy"     => trans2uy($fuel_fee_name),
                        "price"       => $passenger['fuel_fee'],
                        "count"       => 1,
                    ];
                } else {
                    $details[$fuel_fee_key]["count"]++;
                }
                $passengers[$key]['price_details'][] = [
                    "type"        => TripOrderCost::COST_TYPE_PLANE_FUEL_FEE,
                    "parent_type" => TripOrderCost::COST_TYPE_PLANE_FUEL_FEE,
                    "name"        => $fuel_fee_name,
                    "price"       => $passenger['fuel_fee'],
                ];
                $total_price                         += $passenger['fuel_fee'];
                $total_fuel_fee                      += $passenger['fuel_fee'];
            }
            $passengers[$key]['total_price'] = collect($passengers[$key]['price_details'])->sum('price');
        }

        $this->passengers             = $passengers;
        $this->price_details          = [
            'name'        => $name,
            'name_uy'     => trans2uy($name),
            "total_price" => $total_price,
            'details'     => collect($details)->sortBy('type')->values()->toArray(),
        ];
        $this->order_amount           = $total_price;
        $this->total_construction_fee = $total_construction_fee;
        $this->total_fuel_fee         = $total_fuel_fee;
    }

    public function getPriceDetails(): array
    {
        return $this->price_details;
    }

    /**
     * 机建费
     * @return float|int
     */
    public function getTotalConstructionFee(): float|int
    {
        return $this->total_construction_fee;
    }

    /**
     * 燃油费
     * @return float|int
     */
    public function getTotalFuelFee(): float|int
    {
        return $this->total_fuel_fee;
    }

    /**
     * @inheritDoc
     */
    public function calcReceivable(): float
    {
        return $this->getOrderAmount();
    }

    function getOrderAmount(): float
    {
        return $this->order_amount;
    }

    /**
     * @inheritDoc
     */
    public function calcOriginNeedRefundAmount(): float
    {
        return 0;
    }

    public function getPassengers(): array
    {
        return $this->passengers;
    }


}